/*
 * PhotonRTOS础光实时操作系统 -- AUTOSAR计数器内部实现
 *
 * Copyright (C) 2022, 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Lin Yang <s-yanglin@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#ifndef OS_COUNTER_INTERNAL_H
#define OS_COUNTER_INTERNAL_H

#include <autosar/counter.h>
#include <autosar/common.h>
#include <autosar/object.h>
#include <autosar/multicore_internal.h>
#include <autosar/calllevel_internal.h>
#include <autosar/counter_config.h>

typedef VAR(struct autosar_counter, TYPEDEF) OsCounterType;
typedef VAR(struct autosar_counter_waiter, TYPEDEF) OsWaiterType;
typedef VAR(uint8, TYPEDEF) OsWaiterIdType;
typedef P2VAR(OsCounterType, TYPEDEF, OS_APPL_DATA) OsCounterRefType;
typedef P2VAR(OsWaiterType, TYPEDEF, OS_APPL_DATA) OsWaiterRefType;

/* AUTOSAR的Counter结构体 */
struct autosar_counter {
	/**
	 *object: 必须放在结构体的首部，代表counter的父类
	*/
	VAR(OsObjectType, TYPEDEF) object;
	VAR(TickType, TYPEDEF) tick;
	VAR(TickType, TYPEDEF) ticks_per_base;
	VAR(TickType, TYPEDEF) value;
	VAR(TickType, TYPEDEF) max_value;
	VAR(TickType, TYPEDEF) min_cycle;
	VAR(OsListType, TYPEDEF) waiters_list;
	P2VAR(OsWaiterType, TYPEDEF, OS_APPL_DATA) next_waiter;
	VAR(CoreIdType, TYPEDEF) core;
	VAR(CounterType, TYPEDEF) type;
	VAR(OsSpinLockType, TYPEDEF) lock;
};

/* AUTOSAR的Waiter结构体 */
struct autosar_counter_waiter {
	VAR(TickType, TYPEDEF) time;
	VAR(TickType, TYPEDEF) cycle;
	VAR(CounterType, TYPEDEF) counter;
	P2FUNC(void, TYPEDEF, callback)
		(VAR(OsWaiterRefType, AUTOMATIC));
	VAR(OsListType, TYPEDEF) list;
	P2VAR(void, TYPEDEF, OS_APPL_DATA) param;
};

#define SOFTWARE	(CounterType)0x0
#define HARDWARE	(CounterType)0x1

extern VAR(OsCounterType, AUTOMATIC)
	autosar_counters[AUTOSAR_NR_COUNTER];

extern VAR(OsWaiterType, AUTOMATIC)
	autosar_waiters[AUTOSAR_NR_WAITER];


/* 递增一个计数器的实际实现 */
FUNC(StatusType, OS_CODE) __increment_counter(
	VAR(CounterType, AUTOMATIC) CounterID);


/* 唤醒相同时间的需要唤醒的等待者 */
FUNC(void, OS_CODE) __awake_same_time_waiters(
	VAR(CounterType, AUTOMATIC) CounterID);


/* 将一个等待者添加到计数器 */
FUNC(StatusType, OS_CODE) add_waiter_to_counter(
	VAR(OsWaiterRefType, AUTOMATIC) waiter_ref,
	VAR(CounterType, AUTOMATIC) CounterID);

/* 将一个等待者从计数器中移除 */
FUNC(StatusType, OS_CODE) remove_waiter_from_counter(
	VAR(OsWaiterRefType, AUTOMATIC) waiter_ref,
	VAR(CounterType, AUTOMATIC) CounterID);

/* 根据waiter指针获取waiter id，
 * 返回 AUTOSAR_NR_WAITER 表示指针无效 */
FUNC(OsWaiterIdType, OS_CODE) get_waiter_id(
	VAR(OsWaiterRefType, AUTOMATIC) waiter_ref);

FUNC(StatusType, OS_CODE) IncrementHardwareCounter(
	VAR(CounterType, AUTOMATIC) CounterID);


#endif /* OS_COUNTER_INTERNAL_H */

